﻿using Common;
using ComputeSharp;
using log4net.Core;
using System.Diagnostics;
using System.Windows;

namespace GPU.Compute.Demo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    [Injection(InjectionType.Transient)]
    public partial class MainWindow : Window
    {
        Logger _logger;

        public MainWindow(Logger logger)
        {
            InitializeComponent();
            this._logger = logger;
            this.Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            LogHelper.RootPath = "E:/logs/";
            //LogHelper.RootLevel = Level.Debug;
            LogHelper.RootLevelString = "Debug";
            _logger.Info("logger abc1", "abc");
            _logger.Info("logger abcd1", "abcd");
            _logger.Debug("logger abcd2", "abcd");
            _logger.Debug("logger abcd3", "abcd");
            _logger.Debug("logger abc2", "abc");
            _logger.Debug("logger abcd4", "abcd");


            _logger.Info("logger abc1");
            _logger.Info("logger abcd1");
            _logger.Debug("logger abcd2");
            _logger.Debug("logger abcd3");
            _logger.Debug("logger abc2");
            _logger.Debug("logger abcd4");
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var name = "";

            //获取显卡信息，要求支持DirectX12的显卡
            foreach (var graphicsDevice in GraphicsDevice.EnumerateDevices())
            {
                using (graphicsDevice)
                {
                    name = $"{name}GraphicsDevice：{graphicsDevice.Name} ({graphicsDevice.Luid}){System.Environment.NewLine}";
                    Debug.WriteLine($"{graphicsDevice.Name} ({graphicsDevice.Luid})");
                }
            }
            txtName.Text = name;

            //todo：GPU 计算
            var number = Int32.Parse(txtNum.Text.Trim());
            // Allocate a writeable buffer on the GPU, with the contents of the array
            ReadWriteBuffer<Float3> buffer = GraphicsDevice.GetDefault().AllocateReadWriteBuffer<Float3>(number);
            // Run the shader
            int textX = 10;
            int textY = 10;
            int textZ = 10;
            int[] pointList = [.. Enumerable.Range(1, number)];
            ReadWriteBuffer<int> points = GraphicsDevice.GetDefault().AllocateReadWriteBuffer<int>(number);
            points.CopyFrom(pointList);
            GraphicsDevice.GetDefault().For(number, new MyShader(points));
            // Get the data back
            var array = buffer.ToArray();
            Debug.WriteLine(array);

            MessageBox.Show("计算完成！");
        }
    }


    [GeneratedComputeShaderDescriptor]
    [ThreadGroupSize(DefaultThreadGroupSizes.X)]
    public readonly partial struct MyShader(ReadWriteBuffer<int> buffer) : IComputeShader
    {
        public void Execute()
        {
            buffer[ThreadIds.X] = ThreadIds.X;
        }

    }

}